/*
 * Copyright (C) 2009 Alexander Boldyrev
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include "gl_local.h"

/*
 * GL_CreateShader
 */
GLhandleARB GL_CreateShader ( const char * vsh_str, const char * fsh_str )
{
	GLhandleARB program, vsh, fsh;
	GLboolean compiled;
	GLchar str[ 4096 ];

	// Create vertex shader
	vsh = qglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
	qglShaderSourceARB( vsh, 1, &vsh_str, NULL );
	qglCompileShaderARB( vsh );

	// Check for an error
	qglGetObjectParameterivARB( vsh, GL_OBJECT_COMPILE_STATUS_ARB, &compiled );
	if ( !compiled )
	{
		qglGetInfoLogARB( vsh, sizeof (str), NULL, str );
		ri.Sys_Error( ERR_FATAL, "Couldn't compile vertex shader (%s)", str );
		return;
	}

	// Create fragment shader
	fsh = qglCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB );
	qglShaderSourceARB( fsh, 1, &fsh_str, NULL );
	qglCompileShaderARB( fsh );

	// Check for an error
	qglGetObjectParameterivARB( fsh, GL_OBJECT_COMPILE_STATUS_ARB, &compiled );
	if ( !compiled )
	{
		qglGetInfoLogARB( fsh, sizeof (str), NULL, str );
		ri.Sys_Error( ERR_FATAL, "Couldn't compile fragment shader (%s)", str );
		return;
	}

	// Create program
	program = qglCreateProgramObjectARB( );
	qglAttachObjectARB( program, vsh );
	qglAttachObjectARB( program, fsh );
	qglLinkProgramARB( program );

	return program;
}

/*
 * GL_LoadShader
 *
 * fileprefix example:
 * 			"shaders/bump" should load "shader/bump_v.glsl" as vertex
 *			shader and "shader/bump_f.glsl" as fragment shader
 *
 */
GLhandleARB GL_LoadShader ( const char * fileprefix )
{
	char * vsh_str;
	char * fsh_str;
	int len;

	char filename[ MAX_QPATH ]; // FIXME: May be MAX_OSPATH

	//
	// Load vertex shader
	strcpy( filename, fileprefix );
	strcat( filename, "_v.glsl" );

	len = ri.FS_LoadFile( filename, ( void ** ) &vsh_str );
	if ( !vsh_str )
	{
		Com_Printf( PRINT_DEVELOPER, "Bad shader file %s\n", filename );
		return 0;
	}
	// Added zero at end to make a C string
	vsh_str = realloc ( vsh_str, len + 1 );
	vsh_str[ len ] = 0;

	//
	// Load fragment shader
	strcpy( filename, fileprefix );
	strcat( filename, "_f.glsl" );

	len = ri.FS_LoadFile( filename, ( void ** ) &fsh_str );
	if ( !fsh_str )
	{
		Com_Printf( PRINT_DEVELOPER, "Bad shader file %s\n", filename );
		return 0;
	}
	// Added zero at end to make a C string
	fsh_str = realloc ( fsh_str, len + 1 );
	fsh_str[ len ] = 0;

	return GL_CreateShader( vsh_str, fsh_str );
}

/*
 * GL_BindShader
 */
void GL_BindShader ( GLhandleARB program )
{
	static GLhandleARB old_program = 0;
	if ( program == old_program )
		return;
	qglUseProgramObjectARB( program );
}
